use crate::SQLX;
use crate::util::snake::snake_case;




#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
}

use serde_json::{json, Value};

fn get_field_info(obj: &Value) -> Vec<(String, String, Value)> {
    if let Value::Object(map) = obj {
        let mut result = Vec::new();
        for (key, value) in map {
            let field_name = key.clone();
            let field_type = value.type_name();
            result.push((field_name, field_type, value.clone()));
        }
        result
    } else {
        Vec::new()
    }
}

fn main() {
    let person = Person {
        name: String::from("Alice"),
        age: 30,
    };
    let serialized = serde_json::to_value(person).unwrap();
    for (name, ty, value) in get_field_info(&serialized) {
        println!("Field Name: {}, Type: {}, Value: {:?}", name, ty, value);
    }
}

macro_rules! crud_operations {
    ($struct_name:ident) => {
        impl $struct_name {
            pub async fn insert(self) -> anyhow::Result<SqliteQueryResult> {
                let pool = SQLX.get().ok_or(anyhow::anyhow!("db error"))?;
                let mut query_str = format!("INSERT INTO {} (", snake_case(stringify!($struct_name)));

                
                // query!(
                //     "INSERT INTO {} (name, age) VALUES ($1, $2)",
                //     stringify!($struct_name),
                //     &self.name,
                //     &self.age
                // )
                // .execute(pool)
                // .await?;
                Ok(())
            }

            async fn edit(&self, pool: &Pool<Postgres>, id: i32) -> anyhow::Result<SqliteQueryResult> {
                let mut query_str = format!("UPDATE {} SET ", stringify!($struct_name));
                let mut sets = Vec::new();
                let mut params: Vec<&(dyn sqlx::Encode<'_, Postgres> + sqlx::Type<sqlx::Postgres> + Debug)> = Vec::new();

                if let Some(ref name) = self.name {
                    sets.push("name = ?");
                    params.push(name);
                }
                if let Some(age) = self.age {
                    sets.push("age = ?");
                    params.push(&age);
                }

                if sets.is_empty() {
                    println!("没有可更新的字段");
                    return Ok(());
                }

                query_str.push_str(&sets.join(", "));
                query_str.push_str(" WHERE id = ?");
                params.push(&id);

                query(&query_str)
                    .bind_all(params)
                    .execute(pool)
                    .await?;
                Ok(())
            }

            async fn delete(pool: &Pool<Postgres>, id: i32) ->anyhow::Result<SqliteQueryResult> {
                query!("DELETE FROM {} WHERE id = $1", stringify!($struct_name), id)
                    .execute(pool)
                    .await?;
                Ok(())
            }

            async fn find(pool: &Pool<Postgres>, id: i32) -> Result<Option<$struct_name>, sqlx::Error> {
                let user = query_as!(
                    $struct_name,
                    "SELECT name, age FROM {} WHERE id = $1",
                    stringify!($struct_name),
                    id
                )
                .fetch_optional(pool)
                .await?;
                Ok(user)
            }

            async fn page() ->anyhow::Result<Page<todo!()>> {

            }
        }
    };
}
